package server.rest.sessions;

import org.apache.commons.lang.StringUtils;
import server.rest.HttpContext;
import common.ConfigHelper;
import common.ParamHelper;

public class SessionManagerController<KEY, ID, SESSION extends Session<KEY, ID>>
{
    SessionManager<KEY, ID, SESSION> manager;

    public SessionManagerController() throws Exception
    {
        this(null);
    }

    final String paramKey;
    final String headerKey;
    final String cookieKey;

    public SessionManagerController(Expiration<KEY, ID, SESSION> expiration) throws Exception
    {
        String scopeStr = "server.session";
        int timeoutMs = ConfigHelper.getNumberProperty("server.session.timeoutMs", 300 * 1000);
        int buffers = ConfigHelper.getNumberProperty("server.session.buffers", 5);
        manager = new SessionManager<KEY, ID, SESSION>(timeoutMs, buffers, expiration);

        paramKey = ConfigHelper.getScopeStringProperty(scopeStr, "paramKey", "sessionId");
        headerKey = ConfigHelper.getScopeStringProperty(scopeStr, "headerKey", "sessionId");
        cookieKey = ConfigHelper.getScopeStringProperty(scopeStr, "cookieKey", "sessionId");

    }

    public String getKey(HttpContext context)
    {
        String key = ParamHelper.getOptionalQueryString(context, paramKey);

        if (StringUtils.isNotBlank(key))
        {
            return key;
        }
        key = ParamHelper.getHeader(context, headerKey);

        if (StringUtils.isNotBlank(key))
        {
            return key;
        }

        key = ParamHelper.getCookieValue(context, cookieKey);

        if (StringUtils.isNotBlank(key))
        {
            return key;
        }

        return null;
    }

    public SessionManager<KEY, ID, SESSION> getManager()
    {
        return manager;
    }

    public void add(SESSION session)
    {
        manager.add(session);
    }

    public boolean remove(KEY key)
    {
        return manager.remove(key);
    }

    public boolean remove(Session<KEY, ID> session)
    {
        if (null == session)
        {
            return false;
        }
        return manager.remove(session);
    }

    public Session<KEY, ID> getSession(KEY key)
    {
        if (null == key)
            return null;
        return manager.getSession(key);
    }

    public int getTimeoutMs()
    {
        return manager.getTimeoutMs();
    }

    public void setExpiration(Expiration<KEY, ID, SESSION> expiration)
    {
        manager.setExpiration(expiration);
    }

}
